package org.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.exception.BusinessException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Component
@Aspect
public class AopAspject {


    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Pointcut(value = "execution(* org.example.controller.TestController.*(..))")
    public void aaa() {

    }

    @Around(value = "aaa()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();
        Object object = null;
        RateLimit rateLimit = method.getAnnotation(RateLimit.class);

            // 限流逻辑
            int count = rateLimit.count();
            long time = rateLimit.seconds();
            Integer redisCount = (Integer)redisTemplate.opsForValue().get("ratelimit:" + methodName);
            if(redisCount == null){
                redisTemplate.opsForValue().setIfAbsent("ratelimit:" + methodName, count, time, TimeUnit.SECONDS);
                object = joinPoint.proceed();
            }else if(redisCount > 1) {
                redisTemplate.opsForValue().decrement("ratelimit:" + methodName);
                object = joinPoint.proceed();
            }else {
                throw new BusinessException("您已经被限流");
            }
            return  object;
    }
}